package com.gitee.xqlr.graphql.client;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONValidator;
import com.gitee.xqlr.graphql.client.request.GraphqlRequest;
import com.gitee.xqlr.graphql.client.request.GraphqlRequestType;
import com.gitee.xqlr.graphql.client.request.mutation.GraphqlMutation;
import com.gitee.xqlr.graphql.client.request.query.GraphqlQuery;
import com.gitee.xqlr.graphql.client.response.DefaultGraphqlResponse;
import com.gitee.xqlr.graphql.client.response.GraphqlResponse;

/**
 * @author 杜文康
 * @version 1.0
 * @date 2019/8/16 18:14
 */

public class GraphqlClient {

    private final String url;

    private GraphqlClient(String graphqlUrl) {
        this.url = graphqlUrl;
    }

    public static GraphqlClient buildGraphqlClient(String graphqlUrl) {
        return new GraphqlClient(graphqlUrl);
    }

    public <T extends GraphqlQuery> GraphqlResponse doQuery(T query) {
        return doQuery(query, GraphqlRequestType.POST);
    }

    public <T extends GraphqlQuery> GraphqlResponse doQuery(T query, GraphqlRequestType graphqlRequestType) {
        return doHttpRequest(query, graphqlRequestType);
    }

    public <T extends GraphqlMutation> GraphqlResponse doMutation(T mutation) {
        return doMutation(mutation, GraphqlRequestType.POST);
    }

    public <T extends GraphqlMutation> GraphqlResponse doMutation(T mutation, GraphqlRequestType graphqlRequestType) {
        return doHttpRequest(mutation, graphqlRequestType);

    }

    private GraphqlResponse doHttpRequest(GraphqlRequest request, GraphqlRequestType type) {
        String result = null;
        if (type.equals(GraphqlRequestType.POST)) {
            result = HttpKit.post(url, request.body(), request.getHeaders());
        }
        if (result != null && result.contains("{") && JSONValidator.from(result).validate()) {
            DefaultGraphqlResponse response = JSON.parseObject(result, DefaultGraphqlResponse.class);
            Object errors = response.get("errors");
            if (errors == null) {
                return response;
            }
        }
        throw new RuntimeException(String.format("invoke graphql error! operate:%s result:%s", request, result));
    }

    @Override
    public String toString() {
        return "GraphqlClient{" +
                "url='" + url + '\'' +
                '}';
    }
}
